#pragma once
#include <memory>
#include <list>
#include "..\StringLibraries\StringLibraries.h"
namespace re{
namespace event{

class IEventListener;
typedef re::string::StringHandle EventType;
typedef std::tr1::shared_ptr<IEventListener> EventListenerPtr;
class IEventListener
{
public:
	IEventListener() {}
	~IEventListener() {}

	virtual void VHandleEvent() = 0;
};
class IEventData;
typedef std::tr1::shared_ptr<IEventData> EventDataPtr;
class IEventData
{
public:
	IEventData() {}
	~IEventData() {}

	virtual EventType VGetEventType() = 0;
	virtual EventDataPtr VMakeCopy() = 0;
};

//---------------------------------------------------------------------------------------------------
//Event Manager Interface. Making sure threads have connection between each other.
//---------------------------------------------------------------------------------------------------
class IEventManager;

typedef std::tr1::shared_ptr<IEventManager> EventManagerPtr;
typedef std::list<EventType> EventTypeList;
typedef std::list<EventListenerPtr> EventListenerList;
typedef std::map<EventType, EventListenerList> EventTypeMap;

class IEventManager
{
public:
	IEventManager() {  }
	~IEventManager() {  }

	static boost::mutex g_mutex;
	static EventManagerPtr g_EventManager;
	template<class T>
	static const IEventManager* Get()
	{
		if(g_EventManager == EventManagerPtr())
		{
			boost::mutex::scoped_lock lock(g_mutex);
			if(g_EventManager == EventManagerPtr())
			{
				EventManagerPtr pt = EventManagerPtr(new T)
				g_EventManager = ptr;
			}
		}
	}

	virtual void SafeTriggerEvent(const IEventData & data);
	virtual void SafeQueueEvent(const IEventData & data);
	virtual void VSafeTick();

	virtual void VSafeRegisterEvent();
	virtual void VSafeRemoveEvent();
};


}
}